package ru.zombator.taskman.client.query.tcp;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.SocketChannel;
import java.rmi.RemoteException;

import ru.zombator.taskman.core.query.IPacket;
import ru.zombator.taskman.core.query.IResponderCli;
import ru.zombator.taskman.core.utils.PacketUtils;

/**
 * TCP-клиент
 * @author nvamelichev
 *
 */
public class TcpClient implements IResponderCli {
	private final static int TCP_SERVER_PORT = 3333;

	private SocketChannel ch;
	private SocketAddress addr;

	public TcpClient(String ipAddress) throws IOException {
		addr = new InetSocketAddress(ipAddress, TCP_SERVER_PORT);
	}

	@Override
	public IPacket getResponse(IPacket request) throws RemoteException {
		ByteBuffer outBuf = PacketUtils.packetToBuffer(request);		
		try {
			ch = SocketChannel.open(addr);
			ch.configureBlocking(true);
			
			while (outBuf.remaining() != 0) {
				ch.write(outBuf);
			}

			ByteBuffer sizeBuf = ByteBuffer.allocate(4);
			sizeBuf.order(ByteOrder.LITTLE_ENDIAN);
			if (ch.read(sizeBuf) != 4)
				throw new RemoteException("unexpected disconnection");
			sizeBuf.rewind();
			int payloadSize = sizeBuf.getInt();

			ByteBuffer buf = ByteBuffer.allocate(payloadSize);
			buf.order(ByteOrder.LITTLE_ENDIAN);
			if (ch.read(buf) != payloadSize)
				throw new RemoteException("unexpected disconnection");
			buf.rewind();
			
			ch.close();
			return PacketUtils.bufferToPacket(buf, payloadSize);
		} catch (IOException ioe) {
			throw new RemoteException(ioe.getMessage(), ioe);
		}
	}
}
